package com.subway.babynote.syncservice;
import android.database.sqlite.*;
import android.database.*;
import android.content.*;
import com.subway.babynote.*;
import com.subway.babynote.db.TableInfoList;
import com.subway.babynote.db.create_localdb;
import com.subway.babynote.db.logging;
import com.subway.babynote.db.query_clientfeed;
import com.subway.babynote.db.query_clientfeedsum;
import com.subway.babynote.db.query_foods_food;
import com.subway.babynote.db.querybase;
import com.subway.babynote.syncdata.*;
import com.subway.babynote.syncdata.ClientDataRecord.clientFeedRecord;
import com.subway.babynote.syncdata.ClientDataRecord.foodsRecord;
import com.subway.babynote.syncdata.ClientDataRecord.hwAvgRecord;
import com.subway.babynote.syncdata.ClientDataRecord.list_ClientDataRecord;
import com.subway.babynote.syncdata.ClientDataRecord.loadinfoRecord;
import com.subway.babynote.syncdata.ClientDataRecord.tipRecord;
import com.subway.babynote.syncdata.ClientDataRecord.usersRecord;
import com.subway.babynote.syncdata.ClientDataRecord.uxRecord;
import com.subway.babynote.syncdata.ClientDataRecord.weiboRecord;
import com.subway.babynote.syncservice.taskList.tsPair;

import java.util.*;

public class localdbhandler {
	Context _context = null;
	SQLiteDatabase db = null;
	safeobj<ClientDataRecord.usersRecord> users = new safeobj<ClientDataRecord.usersRecord>();
	safeobj<ClientDataRecord.tsType> tscache = new safeobj<ClientDataRecord.tsType>();
	public localdbhandler(Context context)
	{
		this._context = context;
	}
	
	public boolean  init()
	{
		boolean bret = false;
		try
		{
			db = this._context.openOrCreateDatabase(NotedbHelper.DATABASE_NAME, 0, null);
			create_localdb cldb = new create_localdb(db);
			int iret = cldb.createdb();
			if(iret >= 0 )
				bret = true;
			else
				bret = false;
			if(bret)
				users.set(this.read_userRecord());
			if(bret)
				tscache.set(this.init_ts());
			return bret;
		}
		catch(SQLiteException se)
		{
			return false;
		}
	}
	
	public void finalize()
	{
		try
		{
			if(db != null)
			{
				db.close();
				db = null;
			}
		}
		catch(SQLiteException 	se)
		{

			logging.err("localdbhandler.finalize", se.getMessage());
		}
	}
	
	private ClientDataRecord.tsType init_ts()
	{
		ClientDataRecord.tsType ret = new ClientDataRecord.tsType();
		Set<String> keys = ret.c.map.keySet();
		Iterator<String> it = keys.iterator();
		while(it.hasNext())
		{
			String tn = it.next();
			ret.c.map.put(tn, read_ts(tn));
		}
		return ret;
	}
	private void update_ts(String tablename)
	{
		ClientDataRecordBase t = null;
		t = this.read_ts(tablename);
		tscache.get().c.map.put(tablename, t);
	}
	
	private ClientDataRecordBase read_ts(String tablename)
	{
		ClientDataRecordBase ur= null;
		querybase qb = querybase.getinstance(tablename, db);
		if(qb != null)
			ur = qb.getts();
		return ur;
	}
	
	public int get_client_id()
	{
		int client_id = -1;
		ClientDataRecordBase cdrb = this.select(tableName.t_clients, null);
		if(cdrb != null)
		{
			ClientDataRecord.ts t = (ClientDataRecord.ts) cdrb;
			client_id = t.client_id;
		}
		return client_id;
	}
	
	public int update_client_id(int client_id)
	{
		ClientDataRecord.ts t = new ClientDataRecord.ts();
		t.client_id = client_id;
		return this.insert(tableName.t_clients, t, true);
	}
	
	private ClientDataRecord.usersRecord read_userRecord()
	{
		ClientDataRecordBase ur= select(tableName.t_users, null);
		return (ur == null? null: (ClientDataRecord.usersRecord)ur);
	}
	
	public ClientDataRecord.usersRecord get_userRecord()
	{
		return this.users.get();
	}
	
	
	private ClientDataRecordBase select(String tablename,ClientDataRecordBase crb)
	{
		ClientDataRecordBase ret= null;
		querybase qb = querybase.getinstance(tablename, this.db);
		if(qb != null)
			ret = qb.select(crb);
		return ret;
	}
	
	private int insert(String tablename,ClientDataRecordBase crb, boolean delete_old)
	{
		int ret= -1;
		querybase qb = querybase.getinstance(tablename, this.db);
		if(qb != null)
			ret = qb.insert(crb, delete_old);
		return ret;
	}
	
	public int insertweiboitem(ClientDataRecord.weiboRecord wr)
	{
		String tn = tableName.t_weibo;
		int iret = this.insert(tn, wr, false);
		if(iret >= 0)
		{
			this.update_ts(tn);
		}
		return iret;
	}
	
	public int updateUserInfo(ClientDataRecord.usersRecord ur)
	{
		String tn = tableName.t_users;
		int iret = -1;
		try
		{
			db.beginTransaction();
			iret = this.insert(tn, ur, false);
			if(iret >= 0)
				iret = this.copy_default_ux();
			if(iret >= 0)
			{
				this.update_ts(tn);
			}
			db.setTransactionSuccessful();
			return iret;
		}
		catch(Exception ex)
		{
			iret = -1;
			return iret;
		}
		finally
		{
			db.endTransaction();
		}
	}

	public ClientDataRecord.list_ClientDataRecord getFeedRecord(int s_ts, int client_id)
	{
		String tn = tableName.t_feeds;
		ClientDataRecord.feedRecord fr = new ClientDataRecord.feedRecord();
		fr.ts = s_ts;
		fr.client_id = client_id;
		ClientDataRecordBase ret = this.select(tn, fr);
		return (ret == null? null: (ClientDataRecord.list_ClientDataRecord) ret);
	}
	
	private ClientDataRecord.list_ClientDataRecord gethwuser(String tn,int s_ts)
	{
		ClientDataRecord.hwUserRecord hr = new ClientDataRecord.hwUserRecord(0,0,-1);
		hr.ts = s_ts;
		return this.getlist(hr, tn, s_ts);
	}
	
	private ClientDataRecord.list_ClientDataRecord getlist(ClientDataRecordBase input ,String tn,int s_ts)
	{
		ClientDataRecordBase ret = this.select(tn, input);
		return (ret == null? null: (ClientDataRecord.list_ClientDataRecord) ret);
	}
	
	public ClientDataRecord.list_ClientDataRecord gethuserRecord(int s_ts)
	{
		String tn = tableName.t_huser;
		return this.gethwuser(tn,s_ts);
	}
	public ClientDataRecord.list_ClientDataRecord getwuserRecord(int s_ts)
	{
		String tn = tableName.t_wuser;
		return this.gethwuser(tn,s_ts);
	}
	
	public ClientDataRecord.list_ClientDataRecord getweiboRecord(int s_ts)
	{
		String tn = tableName.t_weibo;
		ClientDataRecord.weiboRecord hr = new ClientDataRecord.weiboRecord("","",-1);
		hr.ts = s_ts;
		return this.getlist(hr, tn, s_ts);
	}
	public ClientDataRecord.list_ClientDataRecord getFeedback(int s_ts)
	{
		String tn = tableName.t_feedbacks;
		ClientDataRecord.feedbackRecord hr = new ClientDataRecord.feedbackRecord(0,0,"");
		hr.ts = s_ts;
		return this.getlist(hr, tn, s_ts);
	}
	public ClientDataRecord.list_ClientDataRecord getContact(int s_ts)
	{
		String tn = tableName.t_ourcontact;
		ClientDataRecord.contactRecord cr = new ClientDataRecord.contactRecord(null, null, s_ts);
		
		return this.getlist(cr, tn, s_ts);
	}
	
	public ClientDataRecord.list_ClientDataRecord get_localavg(int s_ts)
	{
		String tn = tableName.t_local_avg;
		ClientDataRecord.last_avgRecord cr = new ClientDataRecord.last_avgRecord(0, 0, "", 0, 0, 0, s_ts);
		
		return this.getlist(cr, tn, s_ts);
	}
	
	public int insertLastAverage (ClientDataRecordBase crb)
	{
		String tn = tableName.t_local_avg;
		int iret = this.insert_updatets(crb, tn, true);
		
		return iret;
	}	
	
	private int insert_updatets(ClientDataRecordBase crb, String tn, boolean delete_old)
	{
		int iret = this.insert(tn, crb, delete_old);
		if(iret >= 0)
		{
			this.update_ts(tn);
		}
		return iret;
	}
	
	public int insertFeeds (ClientDataRecordBase crb)
	{
		String tn = tableName.t_feeds;
		int iret = this.insert_updatets(crb, tn, false);
		
		return iret;
	}	
	public int insertFeedback (ClientDataRecordBase crb)
	{
		String tn = tableName.t_feedbacks;
		int iret = this.insert_updatets(crb, tn, false);
		
		return iret;
	}	
	
	public int insertWeibo (ClientDataRecordBase crb)
	{
		String tn = tableName.t_weibo;
		int iret = this.insert_updatets(crb, tn, false);
		
		return iret;
	}
	
	public int insertHUser (ClientDataRecordBase crb)
	{
		String tn = tableName.t_huser;
		int iret = this.insert_updatets(crb, tn, false);
		
		return iret;
	}
	
	public int insertWUser (ClientDataRecordBase crb)
	{
		String tn = tableName.t_wuser;
		int iret = this.insert_updatets(crb, tn, false);
		
		return iret;
	}
	
	public int insertFoodprop (ClientDataRecordBase crb)
	{
		String tn = tableName.t_food_prop;
		int iret = this.insert_updatets(crb, tn, true);
		
		return iret;
	}
	
	public int insertFoods (ClientDataRecordBase crb)
	{
		String tn = tableName.t_foods;
		int iret = this.insert_updatets(crb, tn, true);
		
		return iret;
	}

	public int insertContact (ClientDataRecordBase crb)
	{
		String tn = tableName.t_ourcontact;
		int iret = this.insert_updatets(crb, tn, true);
		
		return iret;
	}
	
	public int insertLoadinfo (ClientDataRecordBase crb)
	{
		String tn = tableName.t_loadinfo;
		int iret = this.insert_updatets(crb, tn, true);
		
		return iret;
	}
	
	
	public int insert_food_default(ClientDataRecordBase crb)
	{
		String tn = tableName.t_food_default;
		int iret = this.insert_updatets(crb, tn, true);		
		return iret;
	}
	
	public int insert_food_ux(ClientDataRecordBase crb)
	{
		String tn = tableName.t_food_ux;
		int iret = this.insert_updatets(crb, tn, true);		
		return iret;
	}
	
	public int insert_h_default(ClientDataRecordBase crb)
	{
		String tn = tableName.t_h_default;
		int iret = this.insert_updatets(crb, tn, true);		
		return iret;
	}
	
	public int insert_w_default(ClientDataRecordBase crb)
	{
		String tn = tableName.t_w_default;
		int iret = this.insert_updatets(crb, tn, true);		
		return iret;
	}
	

	public int insert_h_ux(ClientDataRecordBase crb)
	{
		String tn = tableName.t_h_ux;
		int iret = this.insert_updatets(crb, tn, true);		
		return iret;
	}
	
	public int insert_w_ux(ClientDataRecordBase crb)
	{
		String tn = tableName.t_w_ux;
		int iret = this.insert_updatets(crb, tn, true);		
		return iret;
	}
	
	
	
	public int insertHeight_AVG(ClientDataRecordBase crb)
	{
		String tn = tableName.t_avg_height;
		int iret = this.insert_updatets(crb, tn, false);		
		return iret;
	}
	public int insertWeight_AVG(ClientDataRecordBase crb)
	{
		String tn = tableName.t_avg_weight;
		int iret = this.insert_updatets(crb, tn, false);		
		return iret;
	}
	
	
	public int insertTip (ClientDataRecordBase crb)
	{
		String tn = tableName.t_tips;
		int iret = this.insert_updatets(crb, tn, false);		
		return iret;
	}
	
	public ClientDataRecord.tsType getts ()
	{
		return tscache.get();
	}
	
	public int clearUserandvisitor()
	{
		String tn = tableName.t_users;
		return this.deletetable(tn);
	}
	
	private int deletetable(String tablename)
	{
		int iret = 0;
		querybase qb = querybase.getinstance(tablename, db);
		if(qb != null)
			iret = qb.delete();
		else
			iret = -1;
		if(iret >= 0)
		{
			this.update_ts(tablename);
		}
		return iret;
	}
		
	public int insertUser(ClientDataRecord.usersRecord ur)
	{
		String tn = tableName.t_users;
		int iret = -1;
		int old_uid = -1;
		ClientDataRecord.usersRecord cachedur = this.get_userRecord();
		if(cachedur != null)
		{
			old_uid = cachedur.user_id;
		}
		querybase qb = querybase.getinstance(tn, this.db);
		if(qb == null)
			iret = -1;
		try
		{
			db.beginTransaction();		
			if(iret >= 0)
				iret = qb.insert(ur, true);
			if((old_uid >= 0) &&(ur.user_id >= 0) &&(old_uid != ur.user_id))
				iret = this.deleteLocalRecord();
			if(iret >= 0)
				iret = this.copy_default_ux();
			db.setTransactionSuccessful();
			return iret;
		}
		catch(Exception ex)
		{
			iret = -1;
			return iret;
		}
		finally
		{
			db.endTransaction();
		}
	}
	
	public int logoutUser()
	{
		int iret = -1;
		try
		{
			String tn = tableName.t_users;
			db.beginTransaction();				
			iret = this.deletetable(tn);	
			if(iret >= 0)
				iret = this.deleteLocalRecord();
			db.setTransactionSuccessful();
			return iret;
		}
		catch(Exception ex)
		{
			iret = -1;
			return iret;
		}
		finally
		{
			db.endTransaction();
		}
	}
	
	private int deleteLocalRecord()
	{
		this.deletetable(tableName.t_clients);
		this.deletetable(tableName.t_feeds);
		this.deletetable(tableName.t_feedbacks);
		this.deletetable(tableName.t_local_avg);
		this.deletetable(tableName.t_weibo);
		this.deletetable(tableName.t_huser);
		this.deletetable(tableName.t_wuser);
		this.deletetable(tableName.t_food_ux);
		this.deletetable(tableName.t_h_ux);
		this.deletetable(tableName.t_w_ux);
		return 0;
	}
	
	public int deleteWeiboRecord()
	{
		return this.deletetable(tableName.t_weibo);
	}
	
	private uxRecord get_weightheight_ux(String tablename,ClientDataRecordBase input)
	{
		ClientDataRecordBase crb = this.select(tablename, input);
		return (crb==null?null:(uxRecord)crb);
	}
	
	public weiboRecord get_weibo()
	{
		String tn = tableName.t_weibo;
		ClientDataRecordBase crb = this.select(tn, null);
		return (crb==null?null:(weiboRecord)crb);
	}
	public loadinfoRecord get_loadinfo() {
		String tn = tableName.t_loadinfo;
		ClientDataRecordBase crb = this.select(tn, null);
		return (crb==null?null:(loadinfoRecord)crb);
	}
	
	private hwAvgRecord get_hwavg(int age, boolean gender, String tn)
	{
		hwAvgRecord hwavg = new hwAvgRecord();
		hwavg.age = age;
		hwavg.gender = gender;
		ClientDataRecordBase crb = this.select(tn, hwavg);
		return (crb==null?null:(hwAvgRecord)crb);
	}
	public hwAvgRecord get_havg(int age, boolean gender)
	{
		String tn = tableName.t_avg_height;
		return this.get_hwavg(age, gender, tn);
	}
	public hwAvgRecord get_wavg(int age, boolean gender)
	{
		String tn = tableName.t_avg_weight;
		return this.get_hwavg(age, gender, tn);
	}
	public foodsRecord getFood(String foodname) 
	{
		query_foods_food qff = new query_foods_food(this.db);
		return qff.getFood(foodname);
	}
	public foodsRecord getFood(int food_id) {
		query_foods_food qff = new query_foods_food(this.db);
		return qff.getFood(food_id);
	}
	public list_ClientDataRecord getFoodbyprop(int food_prop_id)
	{
		query_foods_food qff = new query_foods_food(this.db);
		return qff.getFoodbyprop(food_prop_id);
	}
	public list_ClientDataRecord getFoodybyCategory(String category)
	{
		query_foods_food qff = new query_foods_food(this.db);
		return qff.getFoodybyCategory(category);
	}
	public ClientDataRecordBase get_tip()
	{
		String tn = tableName.t_tips;
		ClientDataRecordBase crb = this.select(tn, null);
		return crb;
	}
	
	public uxRecord get_w_ux()
	{
		String tn = tableName.t_w_ux;
		return this.get_weightheight_ux(tn,null);
	}
	public uxRecord get_h_ux()
	{
		String tn = tableName.t_h_ux;
		return this.get_weightheight_ux(tn, null);
	}
	public uxRecord get_food_ux(int food_id)
	{
		String tn = tableName.t_food_ux;
		ClientDataRecord.food_uxRecord fux = new ClientDataRecord.food_uxRecord();
		fux.food_id = food_id;
		
		return get_weightheight_ux(tn,fux);
	}
		
	private int copy_default_ux()
	{
		int age = -1;
		boolean gender = false;
		usersRecord u = null;
		int iret = -1;
		if(this.get_h_ux() != null)
		{
			iret = 0;
			return iret;
		}
		u = this.get_userRecord();
		if(u == null)
		{
			iret = -1;
			return iret;
		}
		gender = u.gender;
		age = StringUtil.getmonth(u.birth);
		
		ClientDataRecord.food_defaultRecord fdr = new ClientDataRecord.food_defaultRecord();
		fdr.gender = gender;
		fdr.age = age;
		String tn = tableName.t_food_default;
		ClientDataRecord.list_ClientDataRecord food_d =  this.getlist(fdr, tn, 0);
		if(food_d == null)
		iret = -1;
	
		if(iret >=0)
			iret = this.insert_food_ux(food_d);
		
		ClientDataRecord.hwdefaultRecord hdr = new ClientDataRecord.hwdefaultRecord();
		hdr.gender = gender;
		hdr.age = age;
		tn = tableName.t_h_default;
		ClientDataRecord.list_ClientDataRecord h_d =  this.getlist(hdr, tn, 0);
		if(h_d == null)
			iret = -1;
		if(iret >=0)
			iret = this.insert_h_ux(h_d);
		
		tn = tableName.t_w_default;
		ClientDataRecord.list_ClientDataRecord w_d =  this.getlist(hdr, tn, 0);
		if(w_d == null)
			iret = -1;
		if(iret >=0)
			iret = this.insert_w_ux(w_d);
		
		return iret;
		
	}
	
	public ClientDataRecord.list_ClientDataRecord getSumFeeds(int date) {
		query_clientfeed qff = new query_clientfeedsum(this.db);
		return qff.select(date);
	}

	
	public ClientDataRecord.list_ClientDataRecord getFeeds(int date) {
		query_clientfeed qff = new query_clientfeed(this.db);
		return qff.select(date);
	}

}
